package com.briup.MR.index;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.conf.Configured;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.io.Writable;
import org.apache.hadoop.mapreduce.InputSplit;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.Mapper;
import org.apache.hadoop.mapreduce.Reducer;
import org.apache.hadoop.mapreduce.lib.input.FileSplit;
import org.apache.hadoop.mapreduce.lib.input.TextInputFormat;
import org.apache.hadoop.mapreduce.lib.output.TextOutputFormat;
import org.apache.hadoop.util.Tool;
import org.apache.hadoop.util.ToolRunner;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

/**
 yarn jar HdfsClientDemo-1.0-SNAPSHOT.jar com.briup.MR.index.IndexCount -D input=/user/zhang/data -D output=/user/zhang/indexcount_result

 */
public class IndexCount
        extends Configured
            implements Tool {
    static class IndexCountMapper extends Mapper<LongWritable,Text,Text,Text>{
        private Text fn=new Text();
        @Override
        protected void setup(Context context) throws IOException, InterruptedException {
            FileSplit is = (FileSplit) context.getInputSplit();
            String filename = is.getPath().getName();
            fn.set(filename);
        }
        @Override
        protected void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {
            String[] keyword = value.toString().split(" ");
            for (String s:keyword) {
                context.write(new Text(s),fn);
            }
        }
    }
    static class IndexCountReducer extends Reducer<Text,Text,Text,Text>{
        Map<String,Integer> map=new HashMap<String,Integer>();
        @Override
        protected void reduce(Text key, Iterable<Text> values, Context context) throws IOException, InterruptedException {
            for (Text k:values) {
                String file = k.toString();
                if (map.containsKey(file)) {
                    map.put(file, map.get(file) + 1);
                } else {
                    map.put(file, 1);
                }
            }
                StringBuffer sb = new StringBuffer();
                for (Map.Entry<String,Integer> en:map.entrySet()){
                    sb.append(en.getKey()).append(":").append(en.getValue()).append(",");
                }
                sb.setLength(sb.length()-1);
                map.clear();
                context.write(key,new Text(sb.toString()));
        }
    }
    public int run(String[] strings) throws Exception {
        Configuration conf = getConf();
        String input = conf.get("input");
        String output = conf.get("output");

        Job job = Job.getInstance(conf);
        job.setJarByClass(IndexCount.class);
        job.setJobName("IndexCount");

        job.setMapperClass(IndexCountMapper.class);
        job.setMapOutputKeyClass(Text.class);
        job.setMapOutputValueClass(Text.class);

        job.setReducerClass(IndexCountReducer.class);
        job.setOutputKeyClass(Text.class);
        job.setOutputValueClass(Text.class);

        job.setInputFormatClass(TextInputFormat.class);
        job.setOutputFormatClass(TextOutputFormat.class);
        TextInputFormat.addInputPath(job,new Path(input));
        TextOutputFormat.setOutputPath(job,new Path(output));

        return job.waitForCompletion(true)?0:-1;
    }

    public static void main(String[] args) throws Exception {
        System.exit(new ToolRunner().run(new IndexCount(),args));
    }
}
